package com.rankeiot.core.inner;

import com.rankeiot.core.util.JSONUtil;
import com.rankeiot.core.util.StringUtil;
import com.rankeiot.core.util.castor.Castor;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;


import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

public class ListMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return List.class==parameter.getParameterType()&&((ParameterizedType) parameter.getGenericParameterType()).getActualTypeArguments().length==1;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        List list=new ArrayList();
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);

        String param="";
        if( inputMessage.getMethod()== HttpMethod.GET||inputMessage.getMethod()== HttpMethod.DELETE){
            param = webRequest.getParameter(parameter.getParameterName());
        }else if(inputMessage.getHeaders().getContentType().equalsTypeAndSubtype(MediaType.APPLICATION_JSON)){
            param=StringUtil.read(inputMessage.getBody());
        }else{
            param = webRequest.getParameter(parameter.getParameterName());
        }
        if(StringUtil.isEmpty(param)){
            return list;
        }
        Class t= (Class) ((ParameterizedType) parameter.getGenericParameterType()).getActualTypeArguments()[0];
        if(param.startsWith("[")&&param.endsWith("]")){
            list= JSONUtil.parseArray(param,t);
        }else if(param.startsWith("{")&&param.endsWith("}")){
            return JSONUtil.parseObject(param).get(parameter.getParameterName());
        }else{
            String[] paramArr=param.split(",");
            for(String p:paramArr){
                list.add(Castor.castTo(p,t));
            }
        }
        return list;
    }
}
